package gnssio

import (
	"dgo/goutils/utils"
	"time"
)

type CommTaskSender struct {
	listeners       *utils.SafeList
	interval        time.Duration
	stopflag        uint8
	buff            []byte
	inner_data_comm I_Comm
}

func NewCommTaskSender(interval time.Duration, buff []byte) *CommTaskSender {
	rval := &CommTaskSender{
		listeners: utils.NewSafeList(),
		interval:  interval,
		buff:      buff,
	}
	return rval
}

func (this *CommTaskSender) dispatchBuffer(buf []byte, len int) {
	this.listeners.ForEach(func(val interface{}) {
		val.(I_CommListener).OnReceive(this, buf, len)
	})
}

func (this *CommTaskSender) SetInnerDataComm(data_comm I_Comm) {
	if this.inner_data_comm != data_comm {
		if this.inner_data_comm != nil {
			this.inner_data_comm.RemoveListener(this)
		}
		this.inner_data_comm = data_comm
		this.inner_data_comm.AddListener(this)
	}
}

func (this *CommTaskSender) OnReceive(sender I_Comm, buf []byte, l int) {
	this.dispatchBuffer(buf, l)
}

func (this *CommTaskSender) OnConnect(sender I_Comm) {
	this.stopflag = 0
	this.SendPack(sender)
}

func (this *CommTaskSender) OnDisconnect(sender I_Comm) {
	this.stopflag = 1
}

// =================================================================
func (this *CommTaskSender) Start() {
	if this.inner_data_comm != nil {
		this.inner_data_comm.Start()
	}
}

func (this *CommTaskSender) Stop() {
	if this.inner_data_comm != nil {
		this.inner_data_comm.Stop()
	}
}

func (this *CommTaskSender) Send(buf []byte, len int) int {
	return this.inner_data_comm.Send(buf, len)
}

func (this *CommTaskSender) AddListener(event I_CommListener) {
	if this.listeners.Exists(event) {
		utils.Log.Warn("I_CommListener已经存在请勿重复侦听")
		return
	}
	this.listeners.Add(event)
}

func (this *CommTaskSender) RemoveListener(event I_CommListener) {
	this.listeners.Remove(event)
}

func (this *CommTaskSender) SendPack(sender I_Comm) {
	if this.stopflag == 1 {
		return
	}

	utils.Log.Debugf("send:[%s]", string(this.buff))
	sender.Send(this.buff, len(this.buff))

	time.AfterFunc(this.interval, func() {
		this.SendPack(sender)
	})
}
